﻿using ShareCode.Entity.Corpus;
using Infrastructure.Attributes.Ioc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SqlSugar;
using ShareCode.Dto;
using ShareCode.Dto.Corpus;
using ShareCode.Util.Extension;
using System.Linq.Expressions;

namespace Dao.Corpus
{
    /// <summary>
    /// by zhouxin
    ///</summary>
    [Component]
    public class CorpusCorpusDao : BaseContainDateDao<CorpusCorpusEntity>, IRepair2Dao<CorpusCorpusEntity>
    {
        [Autowired]
        public CorpusVersionDao? VersionDao { get; set; }
        // [Autowired]
        // public CorpusSenseDao? CorpusSenseDao { get; set; }


        public override Expressionable<CorpusCorpusEntity> GetSearchExpression(PagingDto pars)
        {
            var whereExpression = base.GetSearchExpression(pars);
            if (pars.SearchField.HasString("SelectedTypeIds"))
            {
                var Aids = pars.SearchField.GetString("SelectedTypeIds")!.Split(',');
                var alIds = new List<long>();

                foreach (var id in Aids)
                {
                    if (long.TryParse(id, out long result))
                    {
                        alIds.Add(result);
                    }
                }

                whereExpression = whereExpression.And(t => alIds.Contains(t.CorpusTypeId));
            }



            return whereExpression;
        }


        public async Task<PagingWithDataModel<CorpusCorpusWithTypeDto>> ListPageWithTypeAsync(PagingDto? pars)
        {
            pars ??= new PagingDto();

            var myreturn = new PagingWithDataModel<CorpusCorpusWithTypeDto>(pars);//自动提取分页参数


            var page = this.TranslatePageModel(myreturn);

            Expression<Func<CorpusCorpusEntity, bool>> whereExpression = GetSearchExpression(pars).ToExpression();
            Expressionable<CorpusCorpusEntity, CorpusTypeEntity> joinWhereExpressionable = new();

            joinWhereExpressionable.And((t, t2) => t.CorpusTypeId == t2.Id);

            if (pars.SearchField.HasLong("VersionId"))
            {
                var ids = await VersionDao!.GetTreeParentIds(pars.SearchField.GetLong("VersionId"));

                joinWhereExpressionable = joinWhereExpressionable.And((t, t2) => ids.Contains(t.VersionId));
            }

            if (pars.SearchField.HasLong("CorpusSenseId"))
            {
                // var ids = await CorpusSenseDao!.GetTreeParentIds(pars.SearchField.GetLong("VersionId"));

                //  joinWhereExpressionable = joinWhereExpressionable.And((t, t2) => ids.Contains(t.CorpusSenseId));
            }
            else
            {
                joinWhereExpressionable = joinWhereExpressionable.And((t, t2) => t.CorpusSenseId == 0);
            }



            Expression<Func<CorpusCorpusEntity, CorpusTypeEntity, bool>> joinWhereExpression = joinWhereExpressionable.ToExpression();
            joinWhereExpression = Expression.Lambda<Func<CorpusCorpusEntity, CorpusTypeEntity, bool>>(Expression.AndAlso(joinWhereExpression.Body, whereExpression.Body), joinWhereExpression.Parameters);

            var query = this.Context.Queryable<CorpusCorpusEntity>()
                .InnerJoin<CorpusTypeEntity>(joinWhereExpression)
                .Select((t, t2) => new CorpusCorpusWithTypeDto { Id = t.Id.SelectAll(), TypeTitle = t2.Title });
            //.Take(pars.TotalRows);

            if (pars.IsDesc.HasValue)
            {
                if (pars.IsDesc.Value)
                {
                    query = query.OrderByDescending(t => t.Id);
                }
                else
                {
                    query = query.OrderBy(t => t.Id);
                }
            }

            myreturn.List = await query.ToListAsync();
            myreturn.TotalRows = page.TotalCount;

            return myreturn;
        }

        public async Task<List<CorpusCorpusWithTypeDto>> ListWithTypeAsync(PagingDto? pars)
        {
            pars ??= new PagingDto();

            Expression<Func<CorpusCorpusEntity, bool>> whereExpression = GetSearchExpression(pars).ToExpression();
            Expressionable<CorpusCorpusEntity, CorpusTypeEntity> joinWhereExpressionable = new();

            joinWhereExpressionable.And((t, t2) => t.CorpusTypeId == t2.Id);

            if (pars.SearchField.HasLong("VersionId"))
            {
                var ids = await VersionDao!.GetTreeParentIds(pars.SearchField.GetLong("VersionId"));

                joinWhereExpressionable = joinWhereExpressionable.And((t, t2) => ids.Contains(t.VersionId) && t.CorpusSenseId == 0);
            }

            Expression<Func<CorpusCorpusEntity, CorpusTypeEntity, bool>> joinWhereExpression = joinWhereExpressionable.ToExpression();
            joinWhereExpression = Expression.Lambda<Func<CorpusCorpusEntity, CorpusTypeEntity, bool>>(Expression.AndAlso(joinWhereExpression.Body, whereExpression.Body), joinWhereExpression.Parameters);

            var query = this.Context.Queryable<CorpusCorpusEntity>()
                .InnerJoin<CorpusTypeEntity>(joinWhereExpression)
                .Select((t, t2) => new CorpusCorpusWithTypeDto { Id = t.Id.SelectAll(), TypeTitle = t2.Title });

            if (pars.IsDesc.HasValue)
            {
                if (pars.IsDesc.Value)
                {
                    query = query.OrderByDescending(t => t.Id);
                }
                else
                {
                    query = query.OrderBy(t => t.Id);
                }
            }

            return await query.ToListAsync();

        }

    }
}
